#include "bsp_mau.h"
#include "bsp_irqn.h"
#define PI                              (3.1415926F)
#define SIN_DELTA                       (1U)
#define SQRT_DELTA                      (1U)
#define SIN_DOT_CNT                     (4096U)
#define SQRT_DATA_CNT                   (4096U)


/**
 * @brief   Interrupt callback function of sqrt Done
 * @param   None
 * @retval  None
 */
static void MAU_SqrtIrqCallback(void)
{
    MAU_SqrtReadDataReg(M4_MAU);
}

/**
 * @brief   Sqrt interrupt init
 * @param   None
 * @retval  None
 */
static void Sqrt_IntCfg(void)
{
    stc_irq_signin_config_t stcIrqSignCfg;
    MAU_SqrtIntCmd(M4_MAU, Enable);

    /* Register IRQ handler && configure NVIC. */
    stcIrqSignCfg.enIRQn = MAU_SQRT_IRQn;
    stcIrqSignCfg.enIntSrc = INT_MAU_SQRT;
    stcIrqSignCfg.pfnCallback = &MAU_SqrtIrqCallback;
    INTC_IrqSignIn(&stcIrqSignCfg);
    NVIC_ClearPendingIRQ(stcIrqSignCfg.enIRQn);
    NVIC_SetPriority(stcIrqSignCfg.enIRQn, DDL_IRQ_PRIORITY_03);
    NVIC_EnableIRQ(stcIrqSignCfg.enIRQn);
}

void bsp_mau_init(void)
{
	PWC_FCG0_Unlock();
	PWC_Fcg0PeriphClockCmd(PWC_FCG0_CORDIC, Enable);
	PWC_FCG0_Lock();
}
void bsp_mau_test(void)
{
	uint32_t u32ErrSqrt = 0U,u32ErrSin = 0U;
	/* 1.Compare the sqrt result generated by mau with the result generated by C library math.h*/
    u32ErrSqrt = Sqrt_Example();
    /* 2.Compare the sine result generated by mau with the result generated by C library math.h*/
    u32ErrSin = Sin_Example();
}
/**
 * @brief Compare the sqrt result generated by mau with the result generated by C library math.h
 * @param  None
 * @retval u32Err
 *           0: Delta is below threshold
 *           1: Delta is above threshold
 */
en_result_t Sqrt_Example(void)
{
    static uint32_t u32Radicands[SQRT_DATA_CNT];
    static uint32_t u32SplGrp[SQRT_DATA_CNT];
    static uint32_t u32CtrlGrp[SQRT_DATA_CNT];
    uint32_t u32CtrlScale = 1U;
    en_result_t enRet = Ok;

    /* Generate random data as radicand parameters for sqrt example */
//    Trng_Gen(u32Radicands,SQRT_DATA_CNT);
	bsp_trng_init();
	bsp_trng_gen(u32Radicands,SQRT_DATA_CNT);
    /* Sqrt configuration */
    Sqrt_IntCfg();
    MAU_SqrtResultLShiftCfg(M4_MAU,0U);
    /* Input random radicands, generate sqrt and compare results */
    for(uint32_t i = 0U; i < SQRT_DATA_CNT; i++)
    {
        /* Generate sample group by mau */
        enRet = MAU_Sqrt(M4_MAU, u32Radicands[i], &u32SplGrp[i]);
        if(Ok == enRet)
        {
            u32SplGrp[i] = (uint32_t)((float32_t)((float32_t)u32SplGrp[i] / (float32_t)u32CtrlScale) + 0.5F);
            /* Generate control group by math.h */
            u32CtrlGrp[i] = (uint32_t)((float32_t)(sqrt((float64_t)u32Radicands[i]) + 0.5F));
            /* Compare result to check error*/
            if(MAU_CheckResidualErr(u32SplGrp[i]
                                    ,(u32CtrlGrp[i])
                                        ,SQRT_DELTA))
            {
                enRet = Error;
            }
        }

        if(Error == enRet)
        {
            break;
        }
    }
    return enRet;
}

/**
 * @brief  Compare the sine result generated by mau with the result generated by C library math.h
 * @param  None
 * @retval u32Err
 *           0: Delta is below threshold
 *           1: Delta is above threshold
 */
uint32_t Sin_Example(void)
{
    static uint32_t u32SplGrp[SIN_DOT_CNT];
    static uint32_t u32CtrlGrp[SIN_DOT_CNT];
    volatile uint16_t u16AvgAngIdx = (uint16_t)(float32_t)((float32_t)MAU_SIN_ANGIDX_TOTAL / (float32_t)SIN_DOT_CNT + (float32_t)0.5);
    uint32_t u32Err = 0U;
    float32_t fAvgRadian;

    if(u16AvgAngIdx == 0U)
    {
        u16AvgAngIdx = 1U;
    }
    fAvgRadian = (float32_t)u16AvgAngIdx / (float32_t)MAU_SIN_ANGIDX_TOTAL * (float32_t)2 * PI;
    for(uint32_t i = 0U; i < SIN_DOT_CNT; i++)
    {
        /* Generate sqrt sample group by mau */
        u32SplGrp[i] = (uint32_t)MAU_Sin(M4_MAU, (uint16_t)(u16AvgAngIdx * i));
        /* Generate sqrt control group by math.h */
        u32CtrlGrp[i] = (uint32_t)(int32_t)(float32_t)(sin(fAvgRadian * (float64_t)i) * (float32_t)MAU_SIN_Q15_SCALAR);
        /* Compare result to check error*/
        if(MAU_CheckResidualErr(u32SplGrp[i]
                                ,(u32CtrlGrp[i])
                                    ,SIN_DELTA))
        {
            u32Err = 1U;
            break;
        }
    }
    return u32Err;
}





